package org.jeecg.modules.api.xxApi.controller;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.api.xxApi.service.IDjts;
import org.jeecg.modules.api.xxApi.vo.*;
import org.jeecg.modules.apiacl.controller.ApiAuthorizeController;
import org.jeecg.modules.innerApi.bwgfApi.service.IBaiWangSkfpService;
import org.jeecg.modules.innerApi.common.requestDto.InvoiceParam;
import org.jeecg.modules.innerApi.common.requestDto.InvoicemxParam;
import org.jeecg.modules.innerApi.common.responseDto.InvoiceRtn;
import org.jeecg.modules.util.FPUtil;
import org.jeecg.modules.util.HttpClientUtil;
import org.jeecg.modules.xxgx.djgl.entity.CsXxDjtsjlDo;
import org.jeecg.modules.xxgx.djgl.entity.cezs.Cezs;
import org.jeecg.modules.xxgx.djgl.entity.tdyw.Hwysfwmx;
import org.jeecg.modules.xxgx.djgl.entity.tdyw.Lkysfwmx;
import org.jeecg.modules.xxgx.djgl.service.ICsXxDjtsjlService;
import org.jeecg.modules.xxgx.fpgl.dto.FpzfDto;
import org.jeecg.modules.xxgx.fpgl.entity.CsXxFpxx;
import org.jeecg.modules.xxgx.fpgl.service.ICsXxFpxxService;
import org.jeecg.modules.xxgx.fpgl.service.IFpkjglService;
import org.jeecg.modules.xxgx.fpgl.vo.YkfpzfRtn;
import org.jeecg.modules.xxgx.fpht.util.DateUtil;
import org.jeecg.modules.xxgx.kpzdgl.entity.CsXxKpzd;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 销项接口管理:单据推送、发票开具
 * @Author: jeecg-boot
 * @Date: 2023-08-02
 * @Version: V1.0
 */
@ApiSort(value = 2)
@Api(tags = "销项接口管理")
@RestController
@RequestMapping(CommonConstant.API + "/xxApi")
@Slf4j
public class DtjsFpkjController extends ApiAuthorizeController {

    @Autowired
    IBaiWangSkfpService baiWangSkfpService;

    @Autowired
    private IDjts iDjts;

    @Autowired
    private ICsXxDjtsjlService iCsXxDjtsjlService;

    @Autowired
    private ICsXxFpxxService iCsXxFpxxService;

    @Autowired
    private IFpkjglService iFpkjglService;

    @Resource(name = "threadPoolTaskExecutor")
    private ThreadPoolTaskExecutor executorService;

    @AutoLog(value = "单据推送")
    @ApiOperation(value = "单据推送", notes = "单据推送", position = 9)
    @PostMapping(value = "/djts")
    public Result djts(@RequestBody @Valid XxApiDjtsListParam list, BindingResult bindingResult) {
        StringBuilder errMsg = new StringBuilder();
        XxApiDjtsResult result = new XxApiDjtsResult();
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError objectError : allErrors) {
                String defaultMessage = objectError.getDefaultMessage();
                errMsg.append(defaultMessage).append(",");
            }
        }
        if (errMsg.length() > 0) {
            CsXxKpzd csXxKpzd = iDjts.queryKpzdBykpzddm(list.getList().get(0).getKpzddm());
            //保存推送记录
            CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
            String djtsjlId = IdWorker.getIdStr();
            csXxDjtsjlDo.setId(djtsjlId);
            csXxDjtsjlDo.setBody(JSONObject.toJSONString(list));
            csXxDjtsjlDo.setStatus("2");
            csXxDjtsjlDo.setTenantId(csXxKpzd.getTenantId().toString());
            csXxDjtsjlDo.setCompanyId(csXxKpzd.getCompanyId());
            csXxDjtsjlDo.setSysOrgCode(StringUtils.isBlank(list.getList().get(0).getBmdm()) ? csXxKpzd.getSysOrgCode() : list.getList().get(0).getBmdm());
            csXxDjtsjlDo.setDjlx(list.getList().get(0).getDjlx());
            csXxDjtsjlDo.setMessage(errMsg.toString());
            iCsXxDjtsjlService.save(csXxDjtsjlDo);
            throw new JeecgBootException(errMsg.toString());
        } else {
            CsXxKpzd csXxKpzd = iDjts.queryKpzdBykpzddm(list.getList().get(0).getKpzddm());
            String tenantId = csXxKpzd.getTenantId().toString();
            String companyid = csXxKpzd.getCompanyId();
            String sysorgcode = StringUtils.isBlank(list.getList().get(0).getBmdm()) ? csXxKpzd.getSysOrgCode() : list.getList().get(0).getBmdm();
            List<XxApiDjtsParam> XxApiDjtsParamlist = list.getList();
            String callBackUrl = list.getCallBackUrl();
            if ("0".equals(list.getAsync())) {
                //同步
                List<XxApiDjtsResult> resultlist = new ArrayList<>();
                if (XxApiDjtsParamlist.size() > 1) {
                    throw new JeecgBootException("同步调用单次只可推送一条单据！");
                }
                XxApiDjtsParam xxApiDjtsParam = XxApiDjtsParamlist.get(0);
                try {
                    result = iDjts.djts(xxApiDjtsParam, "");
                    resultlist.add(result);
                    //保存推送记录
                    CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                    String djtsjlId = IdWorker.getIdStr();
                    csXxDjtsjlDo.setId(djtsjlId);
                    csXxDjtsjlDo.setBody(JSONObject.toJSONString(xxApiDjtsParam));
                    csXxDjtsjlDo.setStatus("0");
                    csXxDjtsjlDo.setTenantId(tenantId);
                    csXxDjtsjlDo.setCompanyId(companyid);
                    csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                    csXxDjtsjlDo.setDjlx(xxApiDjtsParam.getDjlx());
                    iCsXxDjtsjlService.save(csXxDjtsjlDo);
                } catch (Exception e) {
                    log.error(e.getMessage());
                    //保存推送记录
                    CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                    String djtsjlId = IdWorker.getIdStr();
                    csXxDjtsjlDo.setId(djtsjlId);
                    csXxDjtsjlDo.setBody(JSONObject.toJSONString(xxApiDjtsParam));
                    csXxDjtsjlDo.setStatus("2");
                    csXxDjtsjlDo.setTenantId(tenantId);
                    csXxDjtsjlDo.setCompanyId(companyid);
                    csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                    csXxDjtsjlDo.setDjlx(xxApiDjtsParam.getDjlx());
                    csXxDjtsjlDo.setMessage(e.getMessage());
                    iCsXxDjtsjlService.save(csXxDjtsjlDo);
                    throw new JeecgBootException(e.getMessage());
                }
                return Result.OK(resultlist);
            } else if ("1".equals(list.getAsync())) {
                //异步
                if (StringUtils.isBlank(callBackUrl)) {
                    throw new JeecgBootException("异步调用时推送结果回调地址不能为空！");
                }
                //首先保存单据推送记录
                CsXxDjtsjlDo djtsjl = new CsXxDjtsjlDo();
                String djtsjlid = IdWorker.getIdStr();
                djtsjl.setId(djtsjlid);
                djtsjl.setTenantId(tenantId);
                djtsjl.setCompanyId(companyid);
                djtsjl.setSysOrgCode(sysorgcode);
                djtsjl.setDjlx(list.getList().get(0).getDjlx());
                djtsjl.setStatus("-1");//-1 正在处理
                djtsjl.setBody(JSONObject.toJSONString(list));
                djtsjl.setCallbackurl(callBackUrl);
                boolean issave = iCsXxDjtsjlService.save(djtsjl);
                if (issave) {
                    executorService.execute(() -> {
                        TenantContext.setTenant(tenantId);
                        List<XxApiDjtsResult> resultlist = new ArrayList<>();
                        for (XxApiDjtsParam xxApiDjtsParam : XxApiDjtsParamlist) {
                            XxApiDjtsResult djts;
                            try {
                                djts = iDjts.djts(xxApiDjtsParam, callBackUrl);
                                djts.setDjtsjlid(djtsjlid);
                                resultlist.add(djts);
                            } catch (Exception e) {
                                log.error(e.getMessage());
                                XxApiDjtsResult errresult = new XxApiDjtsResult();
                                errresult.setZt("1");
                                errresult.setErrmsg(e.getMessage());
                                errresult.setYwdjbh(xxApiDjtsParam.getYwdjbh());
                                errresult.setSjlx(xxApiDjtsParam.getSjlx());
                                errresult.setDjtsjlid(djtsjlid);
                                resultlist.add(errresult);
                            }
                        }
                        //处理完毕 更新记录
                        LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper = new LambdaUpdateWrapper<>();
                        updateWrapper.eq(CsXxDjtsjlDo::getId, djtsjlid);
                        //处理成功数量
                        int successcount = (int) resultlist.stream().filter(s -> s.getZt().equals("0")).count();
                        //处理失败数量
                        int errcount = (int) resultlist.stream().filter(s -> s.getZt().equals("1")).count();
                        if (successcount > 0 && successcount < XxApiDjtsParamlist.size()) {
                            //部分成功
                            updateWrapper.set(CsXxDjtsjlDo::getStatus, "1");
                        } else if (successcount == XxApiDjtsParamlist.size()) {
                            //全部成功
                            updateWrapper.set(CsXxDjtsjlDo::getStatus, "0");
                        } else {
                            //全部失败
                            updateWrapper.set(CsXxDjtsjlDo::getStatus, "2");
                        }
                        String message = resultlist.stream().map(XxApiDjtsResult::getErrmsg).filter(StringUtils::isNotBlank).collect(Collectors.joining(","));
                        updateWrapper.set(CsXxDjtsjlDo::getMessage, message);
                        iCsXxDjtsjlService.update(updateWrapper);

                        //开始回调
                        log.info("单据推送开始回填，回填url:" + callBackUrl);
                        log.info("单据推送回填内容：" + JSONObject.toJSONString(new Result().OK(resultlist)));
                        try {
                            String callbackresult = HttpClientUtil.doPostJson(callBackUrl, JSONObject.toJSONString(new Result().OK(resultlist)));
                            log.info("单据推送回填结果:" + callbackresult);
                            XxApiCallBackResult xxApiCallBackResult = JSON.parseObject(callbackresult, XxApiCallBackResult.class);
                            if ("200".equals(xxApiCallBackResult.getCode())) {
                                //回调成功
                                LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper1 = new LambdaUpdateWrapper<>();
                                updateWrapper1.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                updateWrapper1.set(CsXxDjtsjlDo::getCallbackstatus, "0");
                                updateWrapper1.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(resultlist)));
                                iCsXxDjtsjlService.update(updateWrapper1);
                            } else {
                                //回调失败
                                LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper2 = new LambdaUpdateWrapper<>();
                                updateWrapper2.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                updateWrapper2.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                                updateWrapper2.set(CsXxDjtsjlDo::getCallbackmessage, xxApiCallBackResult.getMessage());
                                updateWrapper2.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(resultlist)));
                                iCsXxDjtsjlService.update(updateWrapper2);
                            }
                        } catch (Exception e) {
                            //回调没有调通
                            e.printStackTrace();
                            log.error(e.getMessage());
                            LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper3 = new LambdaUpdateWrapper<>();
                            updateWrapper3.eq(CsXxDjtsjlDo::getId, djtsjlid);
                            updateWrapper3.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                            updateWrapper3.set(CsXxDjtsjlDo::getCallbackmessage, e.getMessage());
                            updateWrapper3.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(resultlist)));
                            iCsXxDjtsjlService.update(updateWrapper3);
                        }
                    });
                }
                XxApiDjtsAsyncResult xxApiDjtsAsyncResult = new XxApiDjtsAsyncResult();
                xxApiDjtsAsyncResult.setDjtsjlid(djtsjlid);
                return Result.OK("推送中！", xxApiDjtsAsyncResult);
            } else {
                throw new JeecgBootException("非法异步标识!");
            }
        }
    }

    @AutoLog(value = "发票开具")
    @ApiOperation(value = "发票开具", notes = "发票开具", position = 10)
    @PostMapping(value = "/fpkj")
    public Result fpkj(@RequestBody @Valid XxApiFpkjMainParam fpkj, BindingResult bindingResult) {
        StringBuilder errMsg = new StringBuilder();
        CsXxKpzd csXxKpzd = iDjts.queryKpzdBykpzddm(fpkj.getFpkj().getKpzddm());
        String tenantId = csXxKpzd.getTenantId().toString();
        String companyid = csXxKpzd.getCompanyId();
        String sysorgcode = StringUtils.isBlank(fpkj.getFpkj().getBmdm()) ? csXxKpzd.getSysOrgCode() : fpkj.getFpkj().getBmdm();
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError objectError : allErrors) {
                String defaultMessage = objectError.getDefaultMessage();
                errMsg.append(defaultMessage).append(",");
            }
        }
        if (errMsg.length() > 0) {
            //保存发票开具记录
            CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
            String djtsjlId = IdWorker.getIdStr();
            csXxDjtsjlDo.setId(djtsjlId);
            csXxDjtsjlDo.setBody(JSONObject.toJSONString(fpkj));
            csXxDjtsjlDo.setStatus("2");
            csXxDjtsjlDo.setTenantId(tenantId);
            csXxDjtsjlDo.setCompanyId(companyid);
            csXxDjtsjlDo.setSysOrgCode(sysorgcode);
            csXxDjtsjlDo.setDjlx("fpkj");
            csXxDjtsjlDo.setMessage(errMsg.toString());
            iCsXxDjtsjlService.save(csXxDjtsjlDo);
            throw new JeecgBootException(errMsg.toString());
        } else {
            XxApiFpkjParam fpkjParam = fpkj.getFpkj();
            //首先检查fpsqlsh是否重复
            String clfs = fpkjParam.getClfs();
            if ("0".equals(clfs)) {
                //fpsqlsh 重复时  返回已开发票信息
                String fpsqlsh = fpkjParam.getFpsqlsh();
                List<CsXxFpxx> fpxxlist = iCsXxFpxxService.lambdaQuery().eq(CsXxFpxx::getId, fpsqlsh).list();
                if (!fpxxlist.isEmpty()) {
                    CsXxFpxx csXxFpxx = fpxxlist.get(0);
                    XxApiFpkjResult xxApiFpkjResult = new XxApiFpkjResult();
                    xxApiFpkjResult.setZt("0");
                    xxApiFpkjResult.setFpsqlsh(fpsqlsh);
                    xxApiFpkjResult.setFplxdm(csXxFpxx.getFplxdm());
                    xxApiFpkjResult.setFpdm(csXxFpxx.getFpdm());
                    xxApiFpkjResult.setFphm(csXxFpxx.getFphm());
                    xxApiFpkjResult.setSkm(csXxFpxx.getSkm());
                    xxApiFpkjResult.setJym(csXxFpxx.getJym());
                    xxApiFpkjResult.setEwm(csXxFpxx.getEwm());
                    String kprq = DateUtil.getFormatDate(csXxFpxx.getKprq(), "yyyy-MM-dd HH:mm:ss");
                    xxApiFpkjResult.setKprq(kprq);
                    xxApiFpkjResult.setHjje(csXxFpxx.getHjje());
                    xxApiFpkjResult.setHjse(csXxFpxx.getHjse());
                    xxApiFpkjResult.setJshj(csXxFpxx.getHjje().add(csXxFpxx.getHjse()));
                    return Result.OK(xxApiFpkjResult);
                }
            }
            String callbackurl = fpkj.getCallBackUrl();
            //把接收到的参数转换为发票开具需要的对象
            //发票开具对象
            InvoiceParam invoiceParam = new InvoiceParam();
            BeanUtils.copyProperties(fpkjParam, invoiceParam);
            //处理发票明细赋值
            List<XxApiFpkjMxParam> fpmxs = fpkjParam.getFpmxs();
            List<InvoicemxParam> invoicemxParams = new ArrayList<>();
            for (XxApiFpkjMxParam xxApiFpkjMxParam : fpmxs) {
                InvoicemxParam invoicemxParam = new InvoicemxParam();
                FPUtil.calcItem(xxApiFpkjMxParam, fpkjParam.getTspz());
                BeanUtils.copyProperties(xxApiFpkjMxParam, invoicemxParam);
                invoicemxParams.add(invoicemxParam);
            }
            invoiceParam.setFpmxs(invoicemxParams);
            //处理货物运输明细赋值
            List<Hwysfwmx> tdywHwysfwList = fpkjParam.getTdywHwysfwList();
            if (tdywHwysfwList != null && !tdywHwysfwList.isEmpty()) {
                List<Hwysfwmx> hwysfwmxList = new ArrayList<>();
                for (Hwysfwmx hwysfwmx : tdywHwysfwList) {
                    Hwysfwmx hwysfwmx1 = new Hwysfwmx();
                    BeanUtils.copyProperties(hwysfwmx, hwysfwmx1);
                    hwysfwmxList.add(hwysfwmx1);
                }
                invoiceParam.setTdywHwysfwList(hwysfwmxList);
            }
            //处理旅客运输服务明细
            List<Lkysfwmx> tdywLkysfwList = fpkjParam.getTdywLkysfwList();
            if (tdywLkysfwList != null && !tdywLkysfwList.isEmpty()) {
                List<Lkysfwmx> lkysfwmxList = new ArrayList<>();
                for (Lkysfwmx lkysfwmx : tdywLkysfwList) {
                    Lkysfwmx lkysfwmx1 = new Lkysfwmx();
                    BeanUtils.copyProperties(lkysfwmx, lkysfwmx1);
                    lkysfwmxList.add(lkysfwmx1);
                }
                invoiceParam.setTdywLkysfwList(lkysfwmxList);
            }
            //处理差额征收明细
            List<Cezs> cezsList = fpkjParam.getCezsList();
            if (cezsList != null && !cezsList.isEmpty()) {
                List<Cezs> cezs = new ArrayList<>();
                for (Cezs cezs1 : cezsList) {
                    Cezs cezs2 = new Cezs();
                    BeanUtils.copyProperties(cezs1, cezs2);
                    cezs.add(cezs2);
                }
                invoiceParam.setCezsList(cezs);
            }
            invoiceParam.setKhdzdh(Convert.toStr(fpkjParam.getKhdz(), "") + " " + Convert.toStr(fpkjParam.getKhdh(), ""));
            invoiceParam.setKhyhzh(Convert.toStr(fpkjParam.getKhyh(), "") + " " + Convert.toStr(fpkjParam.getKhzh(), ""));
            invoiceParam.setXfdzdh(Convert.toStr(fpkjParam.getXfdz(), "") + " " + Convert.toStr(fpkjParam.getXfdh(), ""));
            invoiceParam.setXfyhzh(Convert.toStr(fpkjParam.getXfyh(), "") + " " + Convert.toStr(fpkjParam.getXfzh(), ""));

            //处理附加要素
            iDjts.handleFjys(fpkjParam,invoiceParam);

            if ("0".equals(fpkj.getAsync())) {
                //同步
                try {
                    Result<InvoiceRtn.InvoiceRtnData> invoice = iFpkjglService.invoice(invoiceParam);
                    if (invoice.isSuccess()) {
                        //开票成功
                        InvoiceRtn.InvoiceRtnData invoiceRtn = invoice.getResult();
                        XxApiFpkjResult xxApiFpkjResult = new XxApiFpkjResult();
                        BeanUtils.copyProperties(invoiceRtn, xxApiFpkjResult);
                        String kprq = DateUtil.getFormatDate(invoiceRtn.getKprq(), "yyyy-MM-dd HH:mm:ss");
                        xxApiFpkjResult.setKprq(kprq);
                        xxApiFpkjResult.setZt("0");
                        //保存开票记录
                        CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                        String djtsjlId = IdWorker.getIdStr();
                        csXxDjtsjlDo.setId(djtsjlId);
                        csXxDjtsjlDo.setBody(JSONObject.toJSONString(fpkj));
                        csXxDjtsjlDo.setStatus("0");
                        csXxDjtsjlDo.setTenantId(tenantId);
                        csXxDjtsjlDo.setCompanyId(companyid);
                        csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                        csXxDjtsjlDo.setDjlx("fpkj");
                        iCsXxDjtsjlService.save(csXxDjtsjlDo);
                        return Result.OK(xxApiFpkjResult);
                    } else {
                        //开票失败
                        CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                        String djtsjlId = IdWorker.getIdStr();
                        csXxDjtsjlDo.setId(djtsjlId);
                        csXxDjtsjlDo.setBody(JSONObject.toJSONString(fpkj));
                        csXxDjtsjlDo.setStatus("2");
                        csXxDjtsjlDo.setTenantId(tenantId);
                        csXxDjtsjlDo.setCompanyId(companyid);
                        csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                        csXxDjtsjlDo.setDjlx("fpkj");
                        csXxDjtsjlDo.setMessage(invoice.getMessage());
                        iCsXxDjtsjlService.save(csXxDjtsjlDo);
                        return Result.error(invoice.getMessage());
                    }
                } catch (Exception e) {
                    log.error(e.getMessage());
                    CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                    String djtsjlId = IdWorker.getIdStr();
                    csXxDjtsjlDo.setId(djtsjlId);
                    csXxDjtsjlDo.setBody(fpkj.toString());
                    csXxDjtsjlDo.setStatus("2");
                    csXxDjtsjlDo.setTenantId(tenantId);
                    csXxDjtsjlDo.setCompanyId(companyid);
                    csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                    csXxDjtsjlDo.setDjlx("fpkj");
                    csXxDjtsjlDo.setMessage(e.getMessage());
                    iCsXxDjtsjlService.save(csXxDjtsjlDo);
                    throw new JeecgBootException(e.getMessage());
                }
            } else if ("1".equals(fpkj.getAsync())) {
                //异步
                if (StringUtils.isBlank(callbackurl)) {
                    throw new JeecgBootException("异步调用时推送结果回调地址不能为空！");
                }
                //首先保存单据推送记录
                CsXxDjtsjlDo djtsjl = new CsXxDjtsjlDo();
                String djtsjlid = IdWorker.getIdStr();
                djtsjl.setId(djtsjlid);
                djtsjl.setTenantId(tenantId);
                djtsjl.setCompanyId(companyid);
                djtsjl.setSysOrgCode(sysorgcode);
                djtsjl.setDjlx("fpkj");
                djtsjl.setStatus("-1");//-1 正在处理
                djtsjl.setBody(JSONObject.toJSONString(fpkj));
                djtsjl.setCallbackurl(callbackurl);
                boolean issave = iCsXxDjtsjlService.save(djtsjl);
                if (issave) {
                    executorService.execute(() -> {
                        TenantContext.setTenant(tenantId);
                        try {
                            Result<InvoiceRtn.InvoiceRtnData> invoice = iFpkjglService.invoice(invoiceParam);
                            if (invoice.isSuccess()) {
                                //开票成功
                                InvoiceRtn.InvoiceRtnData invoiceRtn = invoice.getResult();
                                XxApiFpkjResult xxApiFpkjResult = new XxApiFpkjResult();
                                BeanUtils.copyProperties(invoiceRtn, xxApiFpkjResult);
                                String kprq = DateUtil.getFormatDate(invoiceRtn.getKprq(), "yyyy-MM-dd HH:mm:ss");
                                xxApiFpkjResult.setZt("0");
                                xxApiFpkjResult.setKprq(kprq);
                                xxApiFpkjResult.setDjtsjlid(djtsjlid);

                                //更新记录
                                LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper = new LambdaUpdateWrapper<>();
                                updateWrapper.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                updateWrapper.set(CsXxDjtsjlDo::getStatus, "0");
                                iCsXxDjtsjlService.update(updateWrapper);

                                //开始回填
                                log.info("开票成功回填，回填url:" + callbackurl);
                                log.info("开票成功回填内容：" + JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                try {
                                    String callbackresult = HttpClientUtil.doPostJson(callbackurl, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                    log.info("开票成功回填请求返回:" + callbackresult);
                                    XxApiCallBackResult xxApiCallBackResult = JSON.parseObject(callbackresult, XxApiCallBackResult.class);
                                    if ("200".equals(xxApiCallBackResult.getCode())) {
                                        //回调成功
                                        LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper1 = new LambdaUpdateWrapper<>();
                                        updateWrapper1.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                        updateWrapper1.set(CsXxDjtsjlDo::getCallbackstatus, "0");
                                        updateWrapper1.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                        iCsXxDjtsjlService.update(updateWrapper1);
                                    } else {
                                        //回调失败
                                        LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper2 = new LambdaUpdateWrapper<>();
                                        updateWrapper2.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                        updateWrapper2.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                                        updateWrapper2.set(CsXxDjtsjlDo::getCallbackmessage, xxApiCallBackResult.getMessage());
                                        updateWrapper2.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                        iCsXxDjtsjlService.update(updateWrapper2);
                                    }
                                } catch (Exception e) {
                                    //回调没有调通
                                    e.printStackTrace();
                                    log.error(e.getMessage());
                                    LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper3 = new LambdaUpdateWrapper<>();
                                    updateWrapper3.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                    updateWrapper3.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                                    updateWrapper3.set(CsXxDjtsjlDo::getCallbackmessage, e.getMessage());
                                    updateWrapper3.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                    iCsXxDjtsjlService.update(updateWrapper3);
                                }
                            } else {
                                //开票失败
                                //更新记录
                                LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper = new LambdaUpdateWrapper<>();
                                updateWrapper.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                updateWrapper.set(CsXxDjtsjlDo::getStatus, "2");
                                updateWrapper.set(CsXxDjtsjlDo::getMessage, invoice.getMessage());
                                iCsXxDjtsjlService.update(updateWrapper);
                                //通知业务系统 开票失败
                                XxApiFpkjResult xxApiFpkjResult = new XxApiFpkjResult();
                                xxApiFpkjResult.setFpsqlsh(fpkj.getFpkj().getFpsqlsh());
                                xxApiFpkjResult.setErrmsg(invoice.getMessage());
                                xxApiFpkjResult.setDjtsjlid(djtsjlid);
                                xxApiFpkjResult.setZt("1");
                                //开始回填
                                log.info("开票失败回填，回填url:" + callbackurl);
                                log.info("开票失败回填内容：" + JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                try {
                                    String callbackresult = HttpClientUtil.doPostJson(callbackurl, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                    log.info("开票失败回填请求返回:" + callbackresult);
                                    XxApiCallBackResult xxApiCallBackResult = JSON.parseObject(callbackresult, XxApiCallBackResult.class);
                                    if ("200".equals(xxApiCallBackResult.getCode())) {
                                        //回调成功
                                        LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper1 = new LambdaUpdateWrapper<>();
                                        updateWrapper1.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                        updateWrapper1.set(CsXxDjtsjlDo::getCallbackstatus, "0");
                                        updateWrapper1.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                        iCsXxDjtsjlService.update(updateWrapper1);
                                    } else {
                                        //回调失败
                                        LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper2 = new LambdaUpdateWrapper<>();
                                        updateWrapper2.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                        updateWrapper2.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                                        updateWrapper2.set(CsXxDjtsjlDo::getCallbackmessage, xxApiCallBackResult.getMessage());
                                        updateWrapper2.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                        iCsXxDjtsjlService.update(updateWrapper2);
                                    }
                                } catch (Exception e) {
                                    //回调没有调通
                                    e.printStackTrace();
                                    log.error(e.getMessage());
                                    LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper3 = new LambdaUpdateWrapper<>();
                                    updateWrapper3.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                    updateWrapper3.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                                    updateWrapper3.set(CsXxDjtsjlDo::getCallbackmessage, e.getMessage());
                                    updateWrapper3.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                    iCsXxDjtsjlService.update(updateWrapper3);
                                }
                            }
                        } catch (Exception e) {
                            log.error(e.getMessage());
                            //业务系统处理失败
                            LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper = new LambdaUpdateWrapper<>();
                            updateWrapper.eq(CsXxDjtsjlDo::getId, djtsjlid);
                            updateWrapper.set(CsXxDjtsjlDo::getStatus, "2");
                            updateWrapper.set(CsXxDjtsjlDo::getMessage, e.getMessage());
                            iCsXxDjtsjlService.update(updateWrapper);

                            //通知业务系统 开票失败
                            XxApiFpkjResult xxApiFpkjResult = new XxApiFpkjResult();
                            xxApiFpkjResult.setFpsqlsh(fpkj.getFpkj().getFpsqlsh());
                            xxApiFpkjResult.setErrmsg(e.getMessage());
                            xxApiFpkjResult.setDjtsjlid(djtsjlid);
                            xxApiFpkjResult.setZt("1");
                            //开始回填
                            log.info("业务系统处理失败回填，回填url:" + callbackurl);
                            log.info("业务系统处理失败回填内容：" + JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                            try {
                                String callbackresult = HttpClientUtil.doPostJson(callbackurl, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                log.info("业务系统处理失败回填请求返回:" + callbackresult);
                                XxApiCallBackResult xxApiCallBackResult = JSON.parseObject(callbackresult, XxApiCallBackResult.class);
                                if ("200".equals(xxApiCallBackResult.getCode())) {
                                    //回调成功
                                    LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper1 = new LambdaUpdateWrapper<>();
                                    updateWrapper1.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                    updateWrapper1.set(CsXxDjtsjlDo::getCallbackstatus, "0");
                                    updateWrapper1.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                    iCsXxDjtsjlService.update(updateWrapper1);
                                } else {
                                    //回调失败
                                    LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper2 = new LambdaUpdateWrapper<>();
                                    updateWrapper2.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                    updateWrapper2.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                                    updateWrapper2.set(CsXxDjtsjlDo::getCallbackmessage, xxApiCallBackResult.getMessage());
                                    updateWrapper2.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                    iCsXxDjtsjlService.update(updateWrapper2);
                                }
                            } catch (Exception e1) {
                                //回调没有调通
                                e1.printStackTrace();
                                log.error(e.getMessage());
                                LambdaUpdateWrapper<CsXxDjtsjlDo> updateWrapper3 = new LambdaUpdateWrapper<>();
                                updateWrapper3.eq(CsXxDjtsjlDo::getId, djtsjlid);
                                updateWrapper3.set(CsXxDjtsjlDo::getCallbackstatus, "1");
                                updateWrapper3.set(CsXxDjtsjlDo::getCallbackmessage, e1.getMessage());
                                updateWrapper3.set(CsXxDjtsjlDo::getCallbackbody, JSONObject.toJSONString(new Result().OK(xxApiFpkjResult)));
                                iCsXxDjtsjlService.update(updateWrapper3);
                            }
                        }
                    });
                }
                XxApiDjtsAsyncResult xxApiDjtsAsyncResult = new XxApiDjtsAsyncResult();
                xxApiDjtsAsyncResult.setDjtsjlid(djtsjlid);
                return Result.OK("开票中！", xxApiDjtsAsyncResult);
            } else {
                throw new JeecgBootException("非法异步标识!");
            }
        }
    }

    @AutoLog(value = "发票作废")
    @ApiOperation(value = "发票作废", notes = "发票作废", position = 11)
    @PostMapping(value = "/fpzf")
    public Result fpzf(@RequestBody @Valid FpzfDto fpzf, BindingResult bindingResult) {
        StringBuilder errMsg = new StringBuilder();
        CsXxKpzd csXxKpzd = iDjts.queryKpzdBykpzddm(fpzf.getKpzddm());
        String tenantId = csXxKpzd.getTenantId().toString();
        String companyid = csXxKpzd.getCompanyId();
        String sysorgcode = csXxKpzd.getSysOrgCode();
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            for (ObjectError objectError : allErrors) {
                String defaultMessage = objectError.getDefaultMessage();
                errMsg.append(defaultMessage).append(",");
            }
        }
        if (errMsg.length() > 0) {
            //保存发票作废记录
            CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
            String djtsjlId = IdWorker.getIdStr();
            csXxDjtsjlDo.setId(djtsjlId);
            csXxDjtsjlDo.setBody(JSONObject.toJSONString(fpzf));
            csXxDjtsjlDo.setStatus("2");
            csXxDjtsjlDo.setTenantId(tenantId);
            csXxDjtsjlDo.setCompanyId(companyid);
            csXxDjtsjlDo.setSysOrgCode(sysorgcode);
            csXxDjtsjlDo.setDjlx("fpzf");
            csXxDjtsjlDo.setMessage(errMsg.toString());
            iCsXxDjtsjlService.save(csXxDjtsjlDo);
            throw new JeecgBootException(errMsg.toString());
        } else {
            try {
                YkfpzfRtn ykfpzf = iFpkjglService.ykfpzf(fpzf);
                if (ykfpzf.isZfzt()) {
                    //作废成功
                    CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                    String djtsjlId = IdWorker.getIdStr();
                    csXxDjtsjlDo.setId(djtsjlId);
                    csXxDjtsjlDo.setBody(JSONObject.toJSONString(fpzf));
                    csXxDjtsjlDo.setStatus("0");
                    csXxDjtsjlDo.setTenantId(tenantId);
                    csXxDjtsjlDo.setCompanyId(companyid);
                    csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                    csXxDjtsjlDo.setDjlx("fpzf");
                    csXxDjtsjlDo.setMessage("作废成功");
                    iCsXxDjtsjlService.save(csXxDjtsjlDo);
                    return Result.OK(ykfpzf);
                } else {
                    //作废失败
                    CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                    String djtsjlId = IdWorker.getIdStr();
                    csXxDjtsjlDo.setId(djtsjlId);
                    csXxDjtsjlDo.setBody(JSONObject.toJSONString(fpzf));
                    csXxDjtsjlDo.setStatus("2");
                    csXxDjtsjlDo.setTenantId(tenantId);
                    csXxDjtsjlDo.setCompanyId(companyid);
                    csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                    csXxDjtsjlDo.setDjlx("fpzf");
                    csXxDjtsjlDo.setMessage(ykfpzf.getMessage());
                    iCsXxDjtsjlService.save(csXxDjtsjlDo);
                    return Result.error(ykfpzf.getMessage());
                }
            } catch (Exception e) {
                CsXxDjtsjlDo csXxDjtsjlDo = new CsXxDjtsjlDo();
                String djtsjlId = IdWorker.getIdStr();
                csXxDjtsjlDo.setId(djtsjlId);
                csXxDjtsjlDo.setBody(JSONObject.toJSONString(fpzf));
                csXxDjtsjlDo.setStatus("2");
                csXxDjtsjlDo.setTenantId(tenantId);
                csXxDjtsjlDo.setCompanyId(companyid);
                csXxDjtsjlDo.setSysOrgCode(sysorgcode);
                csXxDjtsjlDo.setDjlx("fpzf");
                csXxDjtsjlDo.setMessage("作废失败:" + e.getMessage());
                iCsXxDjtsjlService.save(csXxDjtsjlDo);
                return Result.error(e.getMessage());
            }
        }
    }
}
